using System;
using System.Threading.Tasks;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Media;
using Avalonia.Metadata;
using Avalonia.Styling;
using Avalonia.VisualTree;
using AvaloniaUI.Modal.Animations;
using AvaloniaUI.Modal.Services;

namespace AvaloniaUI.Modal.Controls
{
    /// <summary>
    /// 模态对话框宿主控件，负责显示遮罩层和对话框内容
    /// </summary>
    public class ModalHost : TemplatedControl
    {
        #region 依赖属性

        /// <summary>
        /// 定义HostId依赖属性，用于标识不同的ModalHost实例
        /// </summary>
        public static readonly StyledProperty<string> HostIdProperty =
            AvaloniaProperty.Register<ModalHost, string>(nameof(HostId), string.Empty);

        /// <summary>
        /// 定义IsDefault依赖属性，用于标记默认的ModalHost实例
        /// </summary>
        public static readonly StyledProperty<bool> IsDefaultProperty =
            AvaloniaProperty.Register<ModalHost, bool>(nameof(IsDefault), false);

        /// <summary>
        /// 定义IsOpen依赖属性
        /// </summary>
        public static readonly StyledProperty<bool> IsOpenProperty =
            AvaloniaProperty.Register<ModalHost, bool>(nameof(IsOpen));

        /// <summary>
        /// 定义Content依赖属性
        /// </summary>
        public static readonly StyledProperty<object> ContentProperty =
            AvaloniaProperty.Register<ModalHost, object>(nameof(Content));

        /// <summary>
        /// 定义DefaultContent依赖属性，用于存储默认显示的内容
        /// </summary>
        public static readonly StyledProperty<object> DefaultContentProperty =
            AvaloniaProperty.Register<ModalHost, object>(nameof(DefaultContent));

        /// <summary>
        /// 定义Result依赖属性
        /// </summary>
        public static readonly StyledProperty<object> ResultProperty =
            AvaloniaProperty.Register<ModalHost, object>(nameof(Result));

        /// <summary>
        /// 定义OverlayBrush依赖属性
        /// </summary>
        public static readonly StyledProperty<IBrush> OverlayBrushProperty =
            AvaloniaProperty.Register<ModalHost, IBrush>(nameof(OverlayBrush),
                new SolidColorBrush(Color.FromArgb(128, 0, 0, 0)));

        /// <summary>
        /// 定义CloseOnClickOverlay依赖属性
        /// </summary>
        public static readonly StyledProperty<bool> CloseOnClickOverlayProperty =
            AvaloniaProperty.Register<ModalHost, bool>(nameof(CloseOnClickOverlay), true);

        /// <summary>
        /// 定义CloseOnEscape依赖属性
        /// </summary>
        public static readonly StyledProperty<bool> CloseOnEscapeProperty =
            AvaloniaProperty.Register<ModalHost, bool>(nameof(CloseOnEscape), true);

        /// <summary>
        /// 定义Animation依赖属性
        /// </summary>
        public static readonly StyledProperty<ModalAnimation> AnimationProperty =
            AvaloniaProperty.Register<ModalHost, ModalAnimation>(nameof(Animation),
                ModalAnimation.Default);

        #endregion

        #region 属性

        /// <summary>
        /// 获取或设置ModalHost的唯一标识符
        /// </summary>
        public string HostId
        { 
            get => GetValue(HostIdProperty);
            set => SetValue(HostIdProperty, value);
        }

        /// <summary>
        /// 获取或设置一个值，该值指示此ModalHost是否为默认实例
        /// </summary>
        public bool IsDefault
        {
            get => GetValue(IsDefaultProperty);
            set => SetValue(IsDefaultProperty, value);
        }

        /// <summary>
        /// 获取或设置一个值，该值指示对话框是否打开
        /// </summary>
        public bool IsOpen
        {
            get => GetValue(IsOpenProperty);
            set => SetValue(IsOpenProperty, value);
        }

        /// <summary>
        /// 获取或设置对话框内容
        /// </summary>
        public object Content
        {
            get => GetValue(ContentProperty);
            set => SetValue(ContentProperty, value);
        }

        /// <summary>
        /// 获取或设置默认内容
        /// </summary>
        [Content]
        public object DefaultContent
        {
            get => GetValue(DefaultContentProperty);
            set => SetValue(DefaultContentProperty, value);
        }

        /// <summary>
        /// 获取或设置对话框结果
        /// </summary>
        public object Result
        {
            get => GetValue(ResultProperty);
            set => SetValue(ResultProperty, value);
        }

        /// <summary>
        /// 获取或设置遮罩层的画刷
        /// </summary>
        public IBrush OverlayBrush
        {
            get => GetValue(OverlayBrushProperty);
            set => SetValue(OverlayBrushProperty, value);
        }

        /// <summary>
        /// 获取或设置一个值，该值指示是否在点击遮罩层时关闭对话框
        /// </summary>
        public bool CloseOnClickOverlay
        {
            get => GetValue(CloseOnClickOverlayProperty);
            set => SetValue(CloseOnClickOverlayProperty, value);
        }

        /// <summary>
        /// 获取或设置一个值，该值指示是否在按下Esc键时关闭对话框
        /// </summary>
        public bool CloseOnEscape
        {
            get => GetValue(CloseOnEscapeProperty);
            set => SetValue(CloseOnEscapeProperty, value);
        }

        /// <summary>
        /// 获取或设置动画设置
        /// </summary>
        public ModalAnimation Animation
        {
            get => GetValue(AnimationProperty);
            set => SetValue(AnimationProperty, value);
        }

        #endregion

        private TaskCompletionSource<object> _taskCompletionSource;

        /// <summary>
        /// 初始化ModalHost类的新实例
        /// </summary>
        public ModalHost()
        {
            // 默认可见，但模态部分不可交互
            this.IsHitTestVisible = true;
            this.IsVisible = true;
            
            // 如果没有指定HostId，生成一个唯一标识符
            if (string.IsNullOrEmpty(this.HostId))
            {
                this.HostId = Guid.NewGuid().ToString();
            }
        }

        /// <summary>
        /// 当模板应用到控件时调用
        /// </summary>
        protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
        {
            base.OnApplyTemplate(e);

            var overlay = e.NameScope.Find<Panel>("PART_Overlay");
            if (overlay != null)
            {
                overlay.PointerPressed += Overlay_PointerPressed;
            }

            this.KeyDown += ModalHost_KeyDown;
        }

        private void Overlay_PointerPressed(object sender, PointerPressedEventArgs e)
        {
            if (CloseOnClickOverlay)
            {
                Close(null);
            }
        }

        private void ModalHost_KeyDown(object sender, KeyEventArgs e)
        {
            if (CloseOnEscape && e.Key == Key.Escape)
            {
                Close(null);
                e.Handled = true;
            }
        }

        /// <summary>
        /// 异步显示对话框
        /// </summary>
        /// <typeparam name="TResult">结果类型</typeparam>
        /// <returns>对话框结果</returns>
        public Task<TResult> ShowAsync<TResult>()
        {
            _taskCompletionSource = new TaskCompletionSource<object>();
            
            this.IsHitTestVisible = true;
            this.IsVisible = true;
            this.IsOpen = true;

            return _taskCompletionSource.Task.ContinueWith(t => 
            {
                if (t.IsFaulted)
                {
                    throw t.Exception;
                }
                
                return (TResult)t.Result;
            });
        }

        /// <summary>
        /// 关闭对话框
        /// </summary>
        /// <param name="result">对话框结果</param>
        public void Close(object result)
        {
            this.Result = result;
            this.IsOpen = false;
            
            // 保持控件可见，但模态部分不可交互
            this.IsHitTestVisible = true;
            this.IsVisible = true;
            
            if (_taskCompletionSource != null && !_taskCompletionSource.Task.IsCompleted)
            {
                _taskCompletionSource.SetResult(result);
            }
        }

        /// <summary>
        /// 当属性更改时调用
        /// </summary>
        /// <param name="change">属性更改信息</param>
        protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
        {
            base.OnPropertyChanged(change);

            if (change.Property == IsOpenProperty)
            {
                bool isOpen = (bool)change.NewValue;
                // 不再在这里设置IsVisible，保持控件始终可见
                // 只在模态对话框打开时设置IsHitTestVisible
                if (isOpen)
                {
                    this.IsHitTestVisible = true;
                }
            }
        }
        
        /// <summary>
        /// 当控件附加到视觉树时调用
        /// </summary>
        protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
        {
            base.OnAttachedToVisualTree(e);
            
            // 向ModalService注册自己
            ModalService.Instance.RegisterHost(this.HostId, this, this.IsDefault);
        }
        
        /// <summary>
        /// 当控件从视觉树分离时调用
        /// </summary>
        protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
        {
            base.OnDetachedFromVisualTree(e);
            
            // 从ModalService注销自己
            ModalService.Instance.UnregisterHost(this.HostId);
        }
    }
}